package ru.sgu.acm.model;

import org.jacuzzi.mapping.Id;
import org.jacuzzi.mapping.MappedTo;
import org.jacuzzi.mapping.Transient;

import java.util.Date;
import java.util.Properties;
import java.util.Map;
import java.util.HashMap;
import java.io.StringReader;
import java.io.IOException;

/**
 * Submit entity.
 *
 * @author Vitaly Goldshteyn (VitalyGoldstein@gmail.com)
 */
@MappedTo("submits")
public class Submit {
    @Id
    @MappedTo("Id")
    private long id;

    @MappedTo("Contest")
    private long contestId;

    @MappedTo("Task")
    private String taskId;

    @MappedTo("Team")
    private String teamId;

    @MappedTo("Ext")
    private String extension;

    @MappedTo("Time")
    private int time;

    @MappedTo("Memory")
    private int memory;

    @MappedTo("NTest")
    private int testNumber;

    @MappedTo("Accepted")
    private int accepted;

    @MappedTo("Status")
    private String status;

    @MappedTo("judgeAttempt")
    private int judgeAttempt;

    @MappedTo("contesterId")
    private int contesterId;

    //dummy
    @Transient
    int problemPseudoId;
    @Transient
    int pseudoJudge;

    @Transient
    private Properties problemProperties = new Properties();

    @Transient
    private String source;

    /**
     * @return code source of submit.
     */
    public String getSource() {
        return source;
    }

    /**
     * Set code source for this instance only.
     *
     * @param source code
     */
    public void setSource(String source) {
        this.source = source;
    }

    /**
     * Parse properties from string.
     *
     * @param source is ini file with properties.
     */
    public void loadProblemProperties(String source) {
        try {
            problemProperties.load(new StringReader(source));
        } catch (IOException e) {
            throw new IllegalArgumentException(String.format("Unable to parse meta for problem %s of contest %d",
                    taskId, contestId), e);
        }
    }

    /**
     * @return Problem meta properties as {@code Map<String,String>}.
     */
    public Map<String, String> getProblemProperties() {
        Map<String, String> result = new HashMap<String, String>();
        for (Object key : problemProperties.keySet()) {
            result.put(key.toString(), problemProperties.getProperty(key.toString(), ""));
        }
        return result;
    }

    /**
     * @return pseudo judge name from problem properties
     */
    public String getPseudoJudge() {
        return problemProperties.getProperty("pseudoJudge").trim();
    }

    /**
     * Set judge name for this instance only.
     *
     * @param judgeName code
     */
    public void setPseudoJudge(String judgeName) {
        problemProperties.setProperty("pseudoJudge", judgeName);
    }

    /**
     * @return problem id on the remote pseudo judge from problem properties
     */
    public String getProblemPseudoId() {
        return problemProperties.getProperty("pseudoId").trim();
    }

    /**
     * Set problem id on the remote pseudo judge for this instance only.
     *
     * @param problemPseudoId code
     */
    public void setProblemPseudoId(String problemPseudoId) {
        problemProperties.setProperty("pseudoId", problemPseudoId);
    }

    /**
     * @return Date, when submit was recieved.
     */
    public Date getArrived() {
        return arrived;
    }

    public void setArrived(Date arrived) {
        this.arrived = arrived;
    }

    @MappedTo("Arrived")
    private Date arrived;

    public long getContestId() {
        return contestId;
    }

    public void setContestId(long contestId) {
        this.contestId = contestId;
    }

    public String getTaskId() {
        return taskId;
    }

    public void setTaskId(String taskId) {
        this.taskId = taskId;
    }

    /**
     * @return id of team, which send this submit.
     */
    public String getTeamId() {
        return teamId;
    }

    public void setTeamId(String teamId) {
        this.teamId = teamId;
    }

    /**
     * @return extension, which represent programming language of submit.
     */
    public String getExtension() {
        return extension;
    }

    public void setExtension(String extension) {
        this.extension = extension;
    }

    /**
     * @return running time in miliseconds.
     */
    public int getTime() {
        return time;
    }

    public void setTime(int time) {
        this.time = time;
    }

    /**
     * @return memory using in bytes.
     */
    public int getMemory() {
        return memory;
    }

    public void setMemory(int memory) {
        this.memory = memory;
    }

    /**
     * @return number of failed test.
     */
    public int getTestNumber() {
        return testNumber;
    }

    public void setTestNumber(int testNumber) {
        this.testNumber = testNumber;
    }

    /**
     * @return 1 if submit accepted and 0 otherwise
     */
    public int getAccepted() {
        return accepted;
    }

    public void setAccepted(int accepted) {
        this.accepted = accepted;
    }

    /**
     * @return result status of submit
     */
    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    /**
     * @return number of user's attempt
     */
    public int getJudgeAttempt() {
        return judgeAttempt;
    }

    public void setJudgeAttempt(int judgeAttempt) {
        this.judgeAttempt = judgeAttempt;
    }

    /**
     * @return id of contester, which serve this submit.
     */
    public int getContesterId() {
        return contesterId;
    }

    public void setContesterId(int contesterId) {
        this.contesterId = contesterId;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

}
